#pragma once
#include <list>
#include "Instrument.h"
#include "msxml2.h"
#include "Note.h"
#include <vector>
#include "WaveInstrumentFactory.h"
#include "DrumFactory.h"
#include "SubtractiveFactory.h"
#include "AdditiveFactory.h"

class CSynthesizer
{
public:
	CSynthesizer(void);
	virtual ~CSynthesizer(void);

	//! Number of audio channels
	int GetNumChannels() { return mChannels; }

	//! Sample rate in samples per sencond
	double GetSampleRate() { return mSampleRate; }

	//! Sample period in seconds (1/sampleRate)
	double GetSamplePeriod() { return mSamplePeriod; }

	//! Set the number of channels
	void SetNumChannels( int aN ) { mChannels = aN; }

	void SetSampleRate( double aS ) { mSampleRate = aS; mSamplePeriod = 1.0/ aS; }

	void Start ( void );

	bool Generate( double *aFrame );

	double GetTime() { return mTime; }

	void Clear( void );

	void OpenScore( CString & aFileName );

	void XmlLoadScore(IXMLDOMNode *aXml);

	std::vector<double> GetSaw(){return mSawwave;}
	std::vector<double> GetSquare(){return mSquarewave;}
	std::vector<double> GetTriangle(){return mTrianglewave;}
	std::vector<double> CreateSaw();
	std::vector<double> CreateSquare();
	std::vector<double> CreateTriangle();

private:
	int		mChannels;
	double  mSampleRate;
	double  mSamplePeriod;

	std::vector<double> mSawwave;
	std::vector<double> mSquarewave;
	std::vector<double> mTrianglewave;

	double mTime;

	std::list<CInstrument *> mInstruments;

	double mBpm;
	int mBeatspermeasure;
	double mSecperbeat;

	std::vector<CNote> mNotes;

	int mCurrentNote;
	int mMeasure;
	double mBeat;

	void XmlLoadInstrument(IXMLDOMNode * aXml);
	void XmlLoadNote(IXMLDOMNode * xml, std::wstring & instrument);

	//Instrument Factories
	CWaveInstrumentFactory mWaveInstFactory;
	CDrumFactory mDrumFactory;
	CSubtractiveFactory mSubtractiveFactory;
	CAdditiveFactory mAdditiveFactory;
};

